package cn.iocoder.yudao.framework.pay.core.client.impl.kuaishou;

import cn.hutool.crypto.digest.MD5;

/**
 * 快手支付签名计算工具类
 * 用于测试和验证快手支付回调签名
 * 
 * @author 芋道源码
 */
public class KuaishouSignatureCalculator {
    
    /**
     * 快手应用密钥
     */
    private static final String APP_SECRET = "I0qDx3Uj4QA_MX_NLJgUFg";
    
    /**
     * 计算快手支付回调签名
     * 
     * @param body 回调请求体
     * @return 计算出的签名
     */
    public static String calculateSignature(String body) {
        if (body == null || body.isEmpty()) {
            return null;
        }
        
        // 按照快手官方文档：MD5(${http_body_string} + ${app_secret})
        String signStr = body + APP_SECRET;
        String signature = MD5.create().digestHex(signStr).toLowerCase();
        
        System.out.println("=== 快手支付签名计算 ===");
        System.out.println("请求体: " + body);
        System.out.println("应用密钥: " + APP_SECRET);
        System.out.println("待签名字符串: " + signStr);
        System.out.println("计算出的签名: " + signature);
        System.out.println("========================");
        
        return signature;
    }
    
    /**
     * 验证快手支付回调签名
     * 
     * @param body 回调请求体
     * @param receivedSignature 接收到的签名
     * @return 签名是否正确
     */
    public static boolean verifySignature(String body, String receivedSignature) {
        if (body == null || body.isEmpty() || receivedSignature == null || receivedSignature.isEmpty()) {
            return false;
        }
        
        String calculatedSignature = calculateSignature(body);
        boolean isValid = receivedSignature.toLowerCase().equals(calculatedSignature);
        
        System.out.println("=== 快手支付签名验证 ===");
        System.out.println("接收到的签名: " + receivedSignature);
        System.out.println("计算出的签名: " + calculatedSignature);
        System.out.println("验证结果: " + (isValid ? "通过" : "失败"));
        System.out.println("========================");
        
        return isValid;
    }
    
    /**
     * 测试方法
     */
    public static void main(String[] args) {
        // 使用错误日志中的实际回调数据进行测试
        String testBody = "{\"data\":{\"ks_order_no\":\"125070201435938975116\",\"open_id\":null,\"origin\":null,\"channel\":\"WECHAT\",\"other_account_details\":null,\"developer_promotion_amount\":0,\"apple_channel_fee\":null,\"order_amount\":1,\"subsidy_amount\":0,\"out_settle_no\":null,\"refund_amount\":null,\"attach\":\"\",\"app_id\":\"ks679199119974326262\",\"refund_type\":null,\"out_refund_no\":null,\"ks_settle_no\":null,\"out_order_no\":\"P202507021659511\",\"sku_id\":\"\",\"ks_refund_fail_reason\":null,\"apply_refund_reason\":null,\"promotion_amount\":0,\"settle_time\":null,\"pay_time\":1751446802374,\"extra_info\":\"{\\\"url\\\":\\\"\\\",\\\"provider\\\":\\\"\\\",\\\"item_type\\\":\\\"UNKNOWN\\\",\\\"item_id\\\":\\\"\\\",\\\"author_id\\\":\\\"\\\",\\\"refer_id\\\":\\\"\\\",\\\"channel_mark\\\":\\\"\\\",\\\"provider_type\\\":\\\"\\\",\\\"trade_no\\\":\\\"4304002286202507020108723416\\\",\\\"subsidy\\\":0,\\\"upa\\\":0,\\\"acf\\\":0,\\\"withhold_time\\\":0,\\\"withhold_period\\\":0,\\\"withhold_template_id\\\":0,\\\"from_standard_trade_payment\\\":false}\",\"settle_amount\":null,\"refund_time\":null,\"enable_promotion\":false,\"trade_no\":\"4304002286202507020108723416\",\"out_account_id\":\"ks679199119974326262\",\"ks_refund_no\":null,\"status\":\"SUCCESS\",\"user_pay_amount\":0},\"biz_type\":\"PAYMENT\",\"message_id\":\"911c5910-055a-483c-b588-c9c7fdad8b58\",\"app_id\":\"ks679199119974326262\",\"timestamp\":1751446802419}";
        
        // 计算正确的签名
        String correctSignature = calculateSignature(testBody);
        
        // 模拟验证过程
        System.out.println("\n=== 测试签名验证 ===");
        verifySignature(testBody, correctSignature);
        
        // 测试错误签名
        System.out.println("\n=== 测试错误签名 ===");
        verifySignature(testBody, "wrong_signature");
        
        System.out.println("\n=== 使用说明 ===");
        System.out.println("1. 将计算出的签名作为 kwaisign header 发送回调请求");
        System.out.println("2. 回调URL: http://localhost:8080/admin-api/pay/notify/order/40");
        System.out.println("3. 请求方法: POST");
        System.out.println("4. Content-Type: application/json");
        System.out.println("5. 请求体: 上述testBody内容");
    }
}
